<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>7_1_1-2-手动追踪变量的变化 -Proxy包装</title>
</head>

<body>


  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script>
    //定义对象数据
    let a = {
      value: 1,
    };
    let b = {
      value: 2,
    };

    //定义处理器
    handleA = {
      //get是对象的属性值返回的方法
      //get语法将对象属性绑定到查询该属性时将被调用的函数。
      get(target, prop) {
        //对象a，属性
        console.log(`${target[prop]}获取A：${prop}的值`);
        return target[prop];
      },
      //set是属性值修改的方法
      //当尝试设置属性时，set语法将对象属性绑定到要调用的函数。
      set(target, key, value) {
        //对象a，属性， 设置的值
        console.log(`设置A：${key}的值为${value}`);
      },
    };
    handleB = {
      get(target, prop) {
        console.log(`获取B：${prop}的值`);
        return target[prop];
      },
      set(target, key, value) {
        console.log(`设置B：${key}的值为${value}`);
      },
    };

    //let d=new Proxy(target,handle);
    //new Proxy()表示生成一个Proxy实例，(ES6)
    //target参数表示所要拦截的目标对象，
    //handler参数也是一个对象，用来定制拦截行为
    //Proxy 可以理解成，在目标对象之前架设一层“拦截”，外界对该对象的访问，都必须先通过这层拦截，
    //因此提供了一种机制，可以对外界的访问进行过滤和改写
    //作为构造函数，Proxy接受两个参数:
    //第一个参数是所要代理的目标对象，即如果没有Proxy的介入，操作原来要访问的就是这个对象；
    //第二个参数是一个配置对象，对于每一个被代理的操作，需要提供一个对应的处理函数，该函数将拦截对应的操作。

    let pa = new Proxy(a, handleA);
    let pb = new Proxy(b, handleB);
    let sum = pa.value + pb.value; //第一次执行
    console.log("第一次打印，sum的值是：", sum);

    pa.value = 3;
    console.log(`简简单单的测试：`, a.value);
    pb.value = 4;
    console.log("第二次打印，sum的值是：", sum);

    //打印对象
    console.log(JSON.stringify(a));
  </script>
</body>

</html>